#pragma once
// ==================包含头文件====================
#include "hal/gpio.hpp"
#include "ti_msp_dl_config.h"
#include "hal/delay.hpp"
#include "hal/i2c.hpp"
// ================== 包含头文件 ====================
#include <array>

// ==================随配置变动部分====================
using i2c=  hal::i2c1 ;
// ==================随配置变动部分====================

namespace bsp::detail_touch
{

    inline bool touch_int_flag=false; //gpio INT引脚 触发中断
    // ========================== 设备状态码 ==========================
    constexpr int FT6336_OK = 1; ///< 操作成功标志
    constexpr int FT6336_ERROR = 0; ///< 操作失败标志

    // ======================== 设备逻辑状态定义 ========================
    constexpr int FT_FALSE = 0; ///< 逻辑假值（基础状态）
    constexpr int FT_TRUE = 1; ///< 逻辑真值（基础状态）
    constexpr int FT_FALSE1 = 2; ///< 扩展假值1（特殊错误状态）
    constexpr int FT_FALSE2 = 3; ///< 扩展假值2（特殊错误状态）

    // ======================== 设备物理层参数 =========================
    constexpr uint8_t FT6336_ADDR = 0x71; ///< I2C设备地址（7位地址格式）
    // ======================== 寄存器地址定义 =========================
    // --------------------- 基础功能寄存器 --------------------------
    constexpr uint8_t FT_DEVIDE_MODE = 0x00; ///< 模式控制寄存器（默认值：0x00）
    constexpr uint8_t FT_REG_NUM_FINGER = 0x02; ///< 触摸点数量寄存器（0-2个触点）

    // --------------------- 触摸数据寄存器 ----------------------------
    constexpr uint8_t FT_TP1_REG_XH = 0x03; ///< 第1触摸点数据首地址（包含X/Y坐标等数据）
    constexpr uint8_t FT_TP1_REG_XL = 0x04; ///< 第1触摸点数据首地址（包含X/Y坐标等数据）
    constexpr uint8_t FT_TP1_REG_YH = 0x05; ///< 第1触摸点数据首地址（包含X/Y坐标等数据）
    constexpr uint8_t FT_TP1_REG_YL = 0x06; ///< 第1触摸点数据首地址（包含X/Y坐标等数据）
    constexpr uint8_t FT_TP2_REG_XH = 0x09; ///< 第2触摸点数据首地址（包含X/Y坐标等数据）
    constexpr uint8_t FT_TP2_REG_XL = 0x0A; ///< 第2触摸点数据首地址（包含X/Y坐标等数据）
    constexpr uint8_t FT_TP2_REG_YH = 0x0B; ///< 第2触摸点数据首地址（包含X/Y坐标等数据）
    constexpr uint8_t FT_TP2_REG_YL = 0x0C; ///< 第2触摸点数据首地址（包含X/Y坐标等数据）

    // ===================== 芯片识别与控制寄存器 ======================
    constexpr uint8_t FT_ID_G_CIPHER_MID = 0x9F; ///< 芯片代号中字节（默认值：0x26）
    constexpr uint8_t FT_ID_G_CIPHER_LOW = 0xA0; ///< 芯片代号低字节（0x01:FT6336G，0x02:FT6336U）
    constexpr uint8_t FT_ID_G_LIB_VERSION = 0xA1; ///< 固件版本寄存器（只读）
    constexpr uint8_t FT_ID_G_CIPHER_HIGH = 0xA3; ///< 芯片代号高字节（默认值：0x64）
    constexpr uint8_t FT_ID_G_MODE = 0xA4; ///< 中断模式控制寄存器（配置中断触发方式）

    // ====================== 设备配置寄存器 ==========================
    constexpr uint8_t FT_ID_G_FOCALTECH_ID = 0xA8; ///< 厂商ID寄存器（默认值：0x11，只读）
    constexpr uint8_t FT_ID_G_THGROUP = 0x80; ///< 触摸灵敏度寄存器（值越大越灵敏，范围0-80）
    constexpr uint8_t FT_ID_G_PERIODACTIVE = 0x88; ///< 工作周期寄存器（配置扫描频率，单位10ms）

    // ========================= 面板参数 ============================
    constexpr uint8_t PANNEL_ID = 0x11; ///< 面板标识码（用于多面板系统识别，默认0x11）

}



namespace bsp
{
    class touch
    {
    public:
        //触摸初始化函数（驱动芯片FT6336U）（返回1成功返回0失败）
        static uint8_t init()
        {
            // 重置
            TOUCH_RST::low();
            hal::delay::us(10);
            TOUCH_RST::high();
            hal::delay::ms(50);

            std::array<uint8_t, 1> id_reg{100};
            hal::i2c1::readMemory(detail_touch::FT6336_ADDR,detail_touch::FT_ID_G_FOCALTECH_ID , id_reg.data(),id_reg.size());
            return id_reg[0];
        }

        static inline int32_t read_single_point(int32_t *last_x, int32_t *last_y)
        {
            std::array<uint8_t, 1> point_number{};
            std::array<uint8_t, 4> touch_pos{};

            // 读取触摸点的数量
            i2c::readMemory(detail_touch::FT6336_ADDR, detail_touch::FT_REG_NUM_FINGER, point_number.data(),point_number.size()); //读点数

            // 如果没有触摸点，返回0
            if (point_number[0] == 0)
            {
                return 0;
            }

            // 读取第一个触摸点的坐标
            i2c::readMemory(detail_touch::FT6336_ADDR, detail_touch::FT_TP1_REG_XH, touch_pos.data(),touch_pos.size()); //读坐标

            // 解析触摸点的坐标 横屏
            *last_x = 480 - ((static_cast<uint16_t>(touch_pos[2] & 0x0F) << 8) + touch_pos[3]);
            *last_y = (static_cast<uint16_t>(touch_pos[0] & 0x0F) << 8) + touch_pos[1];

            // 返回1表示有触摸点
            return 1;
        }
    };
    class touch_soft
    {
    public:
        using i2c=hal::details_i2c::i2c_config_soft;
        static unsigned char ft6336_write_byte(const unsigned char addr, const unsigned char reg,const unsigned char data)
        {
            i2c::Start();
            i2c::Send_Byte((addr<<1)|0);
            if(i2c::Wait_Ack())
            {
                i2c::Stop();
                return 1;
            }
            i2c::Send_Byte(reg);
            i2c::Wait_Ack();
            i2c::Send_Byte(data);
            if(i2c::Wait_Ack())
            {
                i2c::Stop();
                return 1;
            }
            i2c::Stop();
            return 0;
        }

        static unsigned char ft6336_read_byte(const unsigned char addr,const unsigned char reg)
        {
            i2c::Start();
            i2c::Send_Byte((addr<<1)|0);
            i2c::Wait_Ack();
            i2c::Send_Byte(reg);
            i2c::Wait_Ack();
            i2c::Start();
            i2c::Send_Byte((addr<<1)|1);
            i2c::Wait_Ack();
            const unsigned char res = i2c::Read_Byte(0);
            i2c::Stop();
            return res;
        }

        static unsigned char ft6336_get_td_status()
        {
            const unsigned char a = ft6336_read_byte(detail_touch::FT6336_ADDR, detail_touch::FT_ID_G_FOCALTECH_ID);
            return a;
        }

        static void ft6336_get_touch1_position(unsigned int *x,unsigned int *y)
        {
            unsigned int xh=0,xl=0,yh=0,yl=0;
            xh=ft6336_read_byte(detail_touch::FT6336_ADDR,detail_touch::FT_TP1_REG_XH);
            xl=ft6336_read_byte(detail_touch::FT6336_ADDR,detail_touch::FT_TP1_REG_XL);
            yh=ft6336_read_byte(detail_touch::FT6336_ADDR,detail_touch::FT_TP1_REG_YH);
            yl=ft6336_read_byte(detail_touch::FT6336_ADDR,detail_touch::FT_TP1_REG_YL);
            *x=((xh&0x000F)<<8)|xl;
            *y=((yh&0x000F)<<8)|yl;
        }

        static void ft6336_get_touch2_position(unsigned int *x,unsigned int *y)
        {
            unsigned int xh=0,xl=0,yh=0,yl=0;
            xh=ft6336_read_byte(detail_touch::FT6336_ADDR,detail_touch::FT_TP2_REG_XH);
            xl=ft6336_read_byte(detail_touch::FT6336_ADDR,detail_touch::FT_TP2_REG_XL);
            yh=ft6336_read_byte(detail_touch::FT6336_ADDR,detail_touch::FT_TP2_REG_YH);
            yl=ft6336_read_byte(detail_touch::FT6336_ADDR,detail_touch::FT_TP2_REG_YL);
            *x=((xh&0x000F)<<8)|xl;
            *y=((yh&0x000F)<<8)|yl;
        }

        static void  ft6336_rest()
        {
            TOUCH_RST::low();
            hal::delay::us(10);
            TOUCH_RST::high();
            hal::delay::us( 50000 );
        }
        static void  ft6336_init()
        {
            ft6336_rest();
        }


    };
}
